package controllers

//用户认证
import (
	//	"encoding/json"
	"fmt"
	"gitee.com/lzqysoft/ims/libs"
	"gitee.com/lzqysoft/ims/libs/encrypt"
	"gitee.com/lzqysoft/ims/libs/jwtbeego"
	"gitee.com/lzqysoft/ims/models"
	"github.com/astaxie/beego/utils"

	"time"

	"github.com/astaxie/beego/cache"
	"github.com/astaxie/beego/utils/captcha"

	"github.com/astaxie/beego"
)

//AuthController 认证
type AuthController struct {
	CommonController
}

//Prepare 准备
func (a *AuthController) Prepare() {
	a.EnableXSRF = false
}

//URLMapping 方法映射
func (c *AuthController) URLMapping() {
	c.Mapping("Login", c.Login)
	c.Mapping("Logout", c.Logout)
	c.Mapping("Loginyz", c.Loginyz)
	c.Mapping("Getcpt", c.Getcpt)
	c.Mapping("Vercpt", c.Vercpt)
	c.Mapping("Health", c.Health)
	c.Mapping("MobileIdent", c.MobileIdent)
}

var cpt *captcha.Captcha

//var tokens cache.Cache

func init() {

	// use beego cache system store the captcha data
	store := cache.NewMemoryCache()
	//store := libs.InitCache()
	//	tokens = cache.NewMemoryCache()
	cpt = captcha.NewWithFilter("/captcha/", store)
}

// Getcpt 生成验证码
// @Title 生成验证码
// @Description Getcpt
// @Success 200 {object} cpt
// @Failure 403 : worng
// @router /Getcpt [get]
func (c *AuthController) Getcpt() {
	cpt.StdHeight = 50
	cpt.StdWidth = 150
	cptId, _ := cpt.CreateCaptcha()
	url := fmt.Sprintf("%s%s.png", cpt.URLPrefix, cptId)
	jsond := make(map[string]interface{})
	jsond["cptId"] = cptId
	jsond["url"] = url
	jsond["code"] = 0
	jsond["message"] = "登录成功！"
	c.Data["json"] = jsond
	c.ServeJSON()
}

// Vercpt 验证码验证
// @Title 验证码验证
// @Description Vercpt
// @Param	captcha_id	  query	  string	true	"输入验证码"
// @Param	captcha	  query	  string	true	"验证码id"
// @Success 200 {object} cpt
// @Failure 403 : worng
// @router /Vercpt [post]
func (c *AuthController) Vercpt() {
	//	log.Debug("re is :", c.Ctx.Request)
	cptt := cpt.VerifyReq(c.Ctx.Request)
	jsond := make(map[string]interface{})
	jsond["cptt"] = cptt
	c.Data["json"] = jsond
	c.ServeJSON()

}

// Health 健康检查
// @Title Health
// @Description 健康检查
// @Success 200 Ip
// @Failure 403 : worng
// @router /Health [get]
func (c *AuthController) Health() {
	//	log.Debug("re is :", c.Ctx.Request)
	var jd Jdata
	jd.Code = 0
	jd.Message = "ok"
	c.Data["json"] = jd
	c.ServeJSON()

}

// Logout 退出
// @Title 退出
// @Description User Login by username and pwd
// @Success 200
// @Failure 403
// @router /Logout [get]
func (c *AuthController) Logout() {
	c.DelSession("userinfo")
	c.Redirect("/", 302)
}

// Login 登录
// @Title Login
// @Description User Login by username and pwd
// @Param	name	query	string	true	"admin"
// @Param	pwd	  query	  string	true	"admin"
// @Success 200 {object} models.User
// @Failure 403 :username or pwd was worng
// @router /Login [post]
func (c *AuthController) Login() {
	name := c.GetString("name")
	pswd := c.GetString("pwd")
	jdata := make(map[string]interface{})
	user, err := models.CheckLogin(name, pswd)
	if err == nil {
		//		userprof, _ := models.GetUserprofById(user.Id)
		tokenString := c.Ctx.Input.Header("Authorization")
		et := jwtbeego.EasyToken{
			Userid: user.Id,
			Orgid:  user.Organization.Id,
			Appid:  beego.AppConfig.String("appname"),
		}
		beego.Debug(et)
		beego.Debug(user.Id)
		jwt, ts, err := jwtbeego.Parse(tokenString)
		if err != nil {
			beego.Error(err)
			ts, err = et.GetToken()
			if err != nil {
				beego.Error(err)
				c.RetError(ErrToken)
			}
		} else if jwt.Userid != user.Id {
			beego.Debug(jwt.Userid, user.Id)
			ts, err = et.GetToken()
			if err != nil {
				c.RetError(ErrToken)
			}
		}
		org, _ := models.GetOrganizationById(user.Organization.Id)
		jdata["code"] = 0
		jdata["message"] = "登录成功！"
		jdata["token"] = ts
		jdata["userinfo"] = user
		//		jdata["userprof"] = userprof
		jdata["org"] = org
		c.Data["json"] = jdata
		user.Logincount = user.Logincount + 1
		user.Loginip = c.Ctx.Input.IP()
		user.Logintime = time.Now()
		models.UpdateUserById(user)
		//		c.Dlog("登录系统，用户名为：", user.Id, 2)

	} else {
		jdata["code"] = 1
		jdata["message"] = err.Error()
		c.Data["json"] = jdata

	}

	c.ServeJSON()
}

// Loginyz 登录验证码
// @Title Login 验证码
// @Description User Login by username and pwd
// @Param	name	query	string	true	"admin"
// @Param	pwd	  query	  string	true	"admin"
// @Success 200 {object} models.User
// @Failure 403 :username or pwd was worng
// @router /Loginyz [post]
func (c *AuthController) Loginyz() {
	name := c.GetString("name")
	pswd := c.GetString("pwd")
	captcha := c.GetString("captcha")
	captchaid := c.GetString("captchaid")

	//	jsond := make(map[string]interface{})
	jdata := make(map[string]interface{})
	succe := false
	beego.Debug(name, captchaid, captcha)
	succe = cpt.Verify(captchaid, captcha)
	if succe {
		user, err := models.CheckLogin(name, pswd)
		if err == nil {
			tokenString := c.Ctx.Input.Header("Authorization")
			et := jwtbeego.EasyToken{
				Userid: user.Id,
				Orgid:  user.Organization.Id,
				Appid:  beego.AppConfig.String("appname"),
			}
			beego.Debug(et)
			beego.Debug(user.Id)
			jwt, ts, err := jwtbeego.Parse(tokenString)
			if err != nil {
				beego.Error(err)
				ts, err = et.GetToken()
				beego.Debug("errerr:", err)
				if err != nil {
					beego.Error(err)
					c.RetError(ErrToken)
				}
			} else if jwt.Userid != user.Id {
				beego.Debug(jwt.Userid, user.Id)
				ts, err = et.GetToken()
				if err != nil {
					c.RetError(ErrToken)
				}
			}

			jdata["code"] = 0
			jdata["message"] = "登录成功！"
			jdata["token"] = ts
			//			jsond["user"] = user
			//			jsond["role"] = role
			//			jsond["userprof"] = userprof
			//			jsond["org"] = orginfo
			//			jsond["accesslist"] = accessList
			//			jdata["data"] = jsond
			//			key := []byte(common.Substr(tokenString, 5, 16))
			//			juser, _ := json.Marshal(user)
			//			beego.Debug("juser:", juser)
			//			auser, _ := common.AesEncrypt(juser, key, key)
			//			jdata["aes"] = auser

			c.Data["json"] = jdata

			//			if Ssdbp.Client == nil {
			//				if er := Ssdbp.InitSsdb(); er != nil {
			//					jdata["code"] = 3
			//					jdata["message"] = er.Error()
			//					return
			//				}
			//			}
			//			_, e := Ssdbp.Client.Do("zset", "session", user.Id, time.Now().Unix())

			//			if e != nil {
			//				jdata["code"] = 4
			//				jdata["message"] = e.Error()
			//				log.Error("错误是：", time.Now().Unix(), e)
			//				c.Data["json"] = jdata
			//			}
			user.Logincount = user.Logincount + 1
			user.Loginip = c.Ctx.Input.IP()
			user.Logintime = time.Now()
			models.UpdateUserById(user)
			//			c.Dlog("登录系统，用户名为：", user.Id, 2)
			beego.Debug("errerr:", err)

		} else {
			jdata["code"] = 1
			jdata["message"] = err.Error()
			c.Data["json"] = jdata

		}
	} else {
		jdata["code"] = 2
		jdata["message"] = "验证码错误"
		c.Data["json"] = jdata
	}

	c.ServeJSON()
}

// MobileIdent 手机账号验证
// @Title MobileIdent 验证码
// @Description MobileIdent
// @Param	name	query	string	true	"admin"
// @Param	pwd	  query	  string	true	"admin"
// @Success 200 {object} models.User
// @Failure 403 :username or pwd was worng
// @router /MobileIdent [post]
func (c *AuthController) MobileIdent()  {
	beego.Debug(c.GetString("tdata"))
	tdata, err := c.AesDecode(c.GetString("tdata"))

	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	beego.Debug(tdata)
	sdata := tdata.(map[string]interface{})
	policeName := sdata["policeName"].(string)
	policeAccount := sdata["policeAccount"].(string)
	//deptName := sdata["deptName"].(string)
	deptId := sdata["deptId"].(string)
	jdata := make(map[string]interface{})
	user, err := models.GetUserByUname(policeAccount);
	beego.Debug(user.Dept)
	if err == nil && user.Dept[0].DeptCode == deptId {
		et := jwtbeego.EasyToken{
			Userid: user.Id,
			Orgid:  user.Organization.Id,
			Appid:  beego.AppConfig.String("appname"),
		}
		ts, err := et.GetToken()
		beego.Debug("errerr:", err)
		if err != nil {
			beego.Error(err)
			c.RetError(ErrToken)
		}
		jdata["code"] = 0
		jdata["message"] = "登录成功！"
		jdata["token"] = ts
		c.Data["json"] = jdata
		c.ServeJSON();
	} else if err == nil && user.Dept[0].DeptCode != deptId {
		// 有此用户但信息冲突
		jdata["code"] = 1
		jdata["message"] = "数据异常！"
		c.Data["json"] = jdata
		c.ServeJSON()
	} else if err != nil {
		// 无此用户
		dept, err := models.GetDeptByCode(deptId);
		if err != nil {
			//  没有这个部门
			jdata["code"] = 1
			jdata["message"] = "数据异常！"
			c.Data["json"] = jdata
			c.ServeJSON()
		} else{
			// 添加此用户
			v := &models.User{}
			v.Id = libs.UUID()
			depts := make([]*models.Dept,0)
			depts = append(depts, dept);
			v.Dept = depts
			v.Organization = dept.Organization
			v.Salt = string(utils.RandomCreateBytes(10))
			pwd := beego.AppConfig.String("defaultsPwd")
			v.Pwd = encrypt.EncodeUserPwd(user.Salt, pwd)

			v.Name = policeAccount
			v.Abbr = policeName
			v.Isdelete = 0
			v.Ctime = time.Now()
			v.Creater = "system"
			v.Utime = time.Now()
			v.Updater = "system"
			v.Id = encrypt.GetGuid()
			_, err = models.AddUser(user)
			if err != nil {
				jdata["code"] = 1
				jdata["message"] = "数据异常！"
				c.Data["json"] = jdata
				c.ServeJSON()
			} else {
				et := jwtbeego.EasyToken{
					Userid: v.Id,
					Orgid:  v.Organization.Id,
					Appid:  beego.AppConfig.String("appname"),
				}
				ts, err := et.GetToken()
				beego.Debug("errerr:", err)
				if err != nil {
					beego.Error(err)
					c.RetError(ErrToken)
				}
				jdata["code"] = 0
				jdata["message"] = "登录成功！"
				jdata["token"] = ts
				c.Data["json"] = jdata
				c.ServeJSON();
			}
		}
	}
}

// Loginynz 无验证码登陆
// @Title Loginynz 无验证码登陆
// @Description User Login by username and pwd
// @Param	name	query	string	true	"admin"
// @Param	pwd	  query	  string	true	"admin"
// @Success 200 {object} models.User
// @Failure 403 :username or pwd was worng
// @router /Loginynz [post]
func (c *AuthController) Loginynz() {
	name := c.GetString("name")
	pswd := c.GetString("pwd")

	jdata := make(map[string]interface{})
	user, err := models.CheckLogin(name, pswd)
	if err == nil {
		tokenString := c.Ctx.Input.Header("Authorization")
		et := jwtbeego.EasyToken{
			Userid: user.Id,
			Orgid:  user.Organization.Id,
			Appid:  beego.AppConfig.String("appname"),
		}
		beego.Debug(et)
		beego.Debug(user.Id)
		jwt, ts, err := jwtbeego.Parse(tokenString)
		if err != nil {
			beego.Error(err)
			ts, err = et.GetToken()
			beego.Debug("errerr:", err)
			if err != nil {
				beego.Error(err)
				c.RetError(ErrToken)
			}
		} else if jwt.Userid != user.Id {
			beego.Debug(jwt.Userid, user.Id)
			ts, err = et.GetToken()
			if err != nil {
				c.RetError(ErrToken)
			}
		}

		jdata["code"] = 0
		jdata["message"] = "登录成功！"
		jdata["token"] = ts
		//			jsond["user"] = user
		//			jsond["role"] = role
		//			jsond["userprof"] = userprof
		//			jsond["org"] = orginfo
		//			jsond["accesslist"] = accessList
		//			jdata["data"] = jsond
		//			key := []byte(common.Substr(tokenString, 5, 16))
		//			juser, _ := json.Marshal(user)
		//			beego.Debug("juser:", juser)
		//			auser, _ := common.AesEncrypt(juser, key, key)
		//			jdata["aes"] = auser

		c.Data["json"] = jdata

		//			if Ssdbp.Client == nil {
		//				if er := Ssdbp.InitSsdb(); er != nil {
		//					jdata["code"] = 3
		//					jdata["message"] = er.Error()
		//					return
		//				}
		//			}
		//			_, e := Ssdbp.Client.Do("zset", "session", user.Id, time.Now().Unix())

		//			if e != nil {
		//				jdata["code"] = 4
		//				jdata["message"] = e.Error()
		//				log.Error("错误是：", time.Now().Unix(), e)
		//				c.Data["json"] = jdata
		//			}
		user.Logincount = user.Logincount + 1
		user.Loginip = c.Ctx.Input.IP()
		user.Logintime = time.Now()
		models.UpdateUserById(user)
		//			c.Dlog("登录系统，用户名为：", user.Id, 2)
		beego.Debug("errerr:", err)

	} else {
		jdata["code"] = 1
		jdata["message"] = err.Error()
		c.Data["json"] = jdata

	}

	c.ServeJSON()
}


